package pers.zdb.ag;

import com.alibaba.fastjson.JSON;
import pers.zdb.ag.pojo.Address;
import pers.zdb.ag.pojo.GaodeAddress;
import pers.zdb.ag.pojo.Point;
import pers.zdb.ag.util.FileX;
import pers.zdb.ag.util.GaodeUtils;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * 判断经纬度的地址(由于需要一次性把数据读取到内存（内存间运算速度最快），需要内存性能比较大，<span color="red">运行时请加上</span>: <br>
 * <span color="green">   -Xms558m -Xmx558m -XX:PermSize=1012M -XX:MaxPermSize=1012m    </span>
 * <br>  )
 * @author: Adobe Chow
 * @date: 2018/8/8 18:20
 * @Copyright: www.winshang.com Inc. All rights reserved.
 */
public class AddressUtils {


    public static void main(String[] args) {

        for (int i=1;i<40;i++){
        //目测单线程速度快于多线程
//        new Thread(new Runnable() {
//            @Override
//            public void run() {
//                long ttt = System.currentTimeMillis();
//                Address address = getAddress(114.692845,23.752599);
//                System.out.println(address.getProvince()+"-"+address.getCity()+"-"+address.getArea());
//                System.out.println("耗时:"+(System.currentTimeMillis()-ttt));
//            }
//        }).start();

//            long ttt = System.currentTimeMillis();
//            Address address = getAddress(114.692845,23.752599);
//            System.out.println(address.getProvince()+"-"+address.getCity()+"-"+address.getArea());
//            System.out.println("耗时"+i+":  "+(System.currentTimeMillis()-ttt));

        }

    }


    /**
     * 获取经纬度的省市区( <span color="green">   -Xms558m -Xmx558m -XX:PermSize=1012M -XX:MaxPermSize=1012m    </span> )
     * @param longitude
     * @param latitude
     * @return
     */
    public static Address getAddress(double longitude, double latitude){
//        long ttt = System.currentTimeMillis();
        List<GaodeAddress> list = AddressUtils.getGaodeAddressList();
//        System.out.println("getGaodeAddressList耗时:"+(System.currentTimeMillis()-ttt));
        List<GaodeAddress> provinceList = new ArrayList<>();
        List<GaodeAddress> cityList = new ArrayList<>();
        List<GaodeAddress> areaList = new ArrayList<>();

        for (GaodeAddress gaodeAddress:list) {
            if (new Integer(1).equals(gaodeAddress.getLevelCode())){
                provinceList.add(gaodeAddress);
            }else if (new Integer(2).equals(gaodeAddress.getLevelCode())){
                cityList.add(gaodeAddress);
            }else if (new Integer(3).equals(gaodeAddress.getLevelCode())){
                areaList.add(gaodeAddress);
            }
        }

        Address address = new Address();

        for (GaodeAddress province:provinceList) {
            if (isInGaodeAddress(longitude,latitude,province.getPolyline())){
                //省
                address.setProvince(province.getName());

                for (GaodeAddress city:cityList) {
                    if (city.getParentAdcode().equals(province.getAdcode()) && isInGaodeAddress(longitude,latitude,city.getPolyline())){
                        //市
                        address.setCity(city.getName());

                        for (GaodeAddress area:areaList) {
                            if (area.getParentAdcode().equals(city.getAdcode()) && isInGaodeAddress(longitude,latitude,area.getPolyline())){
                                //区
                                address.setArea(area.getName());
                                break;
                            }
                        }

                        break;
                    }
                }

                break;
            }
        }
        return address;
    }

//    判断点是否在圈内
    private static boolean isInGaodeAddress(double longitude, double latitude, String polyline) {
        String[] areas = polyline.split("\\|");
        for (String area:areas) {
            String[] points = area.split(";");
            List<Point> poiList = new ArrayList<>();
            for (String point:points) {
                String lng = point.split(",")[0];
                String lat = point.split(",")[1];

                Point poi = new Point();
                poi.setLatitude(Double.parseDouble(lat));
                poi.setLongitude(Double.parseDouble(lng));
                poiList.add(poi);
            }

            if (GaodeUtils.IsPtInPoly(longitude,latitude,poiList)){
                return true;
            }

        }

        return false;
    }


    private static List<GaodeAddress>  gaodeAddressList = null;

    /**
     * 从本地资源文件获取数据(防止内存泄漏，别用静态方法)
     * @return
     */
    public static synchronized   List<GaodeAddress> getGaodeAddressList(){
        if (gaodeAddressList!=null){
            return gaodeAddressList;
        }

        gaodeAddressList = new ArrayList<>();
        String path = AddressUtils.class.getClassLoader().getResource("data").getPath();
        System.out.println(path);

        String[] pathArr = new File(path).list();
        for (String filePath:pathArr) {
//            System.out.println(path+"/"+filePath);
            String str = FileX.read(path+"/"+filePath);
//            System.out.println(str);
            if (str!=null){
                GaodeAddress gaodeAddress = JSON.toJavaObject(JSON.parseObject(str),GaodeAddress.class);
                gaodeAddressList.add(gaodeAddress);
            }
        }
        return gaodeAddressList;
    }

}
